<!DOCTYPE html>
<html lang="zh-CN">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>数字滚动</title>
  <style>
    *,
    *::after,
    *::before {
      margin: 0;
      padding: 0;
      box-sizing: border-box;
    }

    :root {
      min-height: 100vh;
    }

    :root:focus-within {
      scroll-behavior: smooth;
    }

    body {
      min-height: inherit;
      background-color: #68734a;
      display: flex;
      flex-direction: column;
      align-items: center;
      justify-content: center;
    }

    main {
      width: 500px;
      height: 90px;
      display: flex;
      align-items: center;
      justify-content: space-between;
    }

    .item {
      position: relative;
      width: 90px;
      height: 90px;
      border: 1px dashed #8bffa1;
      border-radius: 50%;
      transform: scaleX(0.8);
      background-color: rgba(0, 0, 0, 0.2);
    }

    .item:nth-child(1) {
      border-color: #8bffa1;
      color: #8bffa1;
    }

    .item:nth-child(2) {
      border-color: #92fffe;
      color: #92fffe;
    }

    .item:nth-child(3) {
      border-color: #fbfd97;
      color: #fbfd97;
    }

    .item:nth-child(4) {
      border-color: #45ffca;
      color: #45ffca;
    }

    .item:nth-child(5) {
      border-color: #ffe900;
      color: #ffe900;
    }

    ul {
      list-style: none;
      width: 100%;
      position: absolute;
      left: 0;
      top: 0;
      transition: all 0.25s ease-in-out 0s;
    }

    ul>li {
      width: 90px;
      height: 90px;
      display: inline-flex;
      justify-content: center;
      align-items: center;
      font-size: 60px;
      font-weight: bold;
      transform: scaleX(1.25);
    }
  </style>
</head>

<body>
  <main id="main"></main>
</body>
<script>
  "use strict"; {
    class NumRoll {
      constructor(opt = {}) {
        // 获取到main
        this.el = document.getElementById(opt.id)
        this.initHtml()
        // 获取所有的ul
        this.uls = this.el.querySelectorAll("ul")
        // 绑定滚动结束后的事件
        this.uls.forEach(ul => {
          ul.addEventListener("transitionend", () => {

          })
        })
      }

      data = [0, 0, 0, 0, 0]

      setData(data) {
        let str = String(data)
        let len = str.length
        if (len <= 5) str.padStart(5, "0");
        this.data = Array.from(str).map(v => Number(v))
        return this
      }

      // 初始html结构
      initHtml() {
        let len = this.data.length;
        let html = []
        for (let i = 0; i < len; i++) {
          // 记录一下当前的数字
          let v = this.data[i]
          let li = []
          for (let j = 0; j < 10; j++) {
            li.push(`<li>${j}</li>`)
          }
          html.push(`
            <div class="item">
                <ul data-v="${v}">${li.join("")}</ul>
            </div>
          `)
        }
        this.el.innerHTML = html.join("");

      }

      // 重新绘制底部的数据
      renderBottomNum(ul, v) {

      }

      // 滚动单个数字
      runOneNum(v, k) {
        let ul = this.uls[k]
        // 上一次移动的值
        let preV = ul.dataset["v"] ?? 0
        let course = v - preV;
        if (preV > v) {
          course = 10 - preV + v
        }
        ul.dataset["v"] = v;

        // 移动的距离
        let dis = (course * -90) + "px"
        ul.style.transform = `translate3d(0,${dis},0)`;
      }

      // 滚动数字
      run() {
        this.data.forEach((v, k) => {
          this.runOneNum(v, k);
        })
      }
    }

    const numRoll = new NumRoll({
      id: "main",
    })

    setTimeout(() => {
      numRoll.setData(12345).run()
    }, 2.5 * 1000)
  };
</script>

</html>